package goquerys

import (
	"errors"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	lua "github.com/yuin/gopher-lua"
	"reflect"
)

//func Register_4lua(l *lua.LState) {
//	l.SetGlobal("GoQuery", l.SetFuncs(l.NewTable(), map[string]lua.LGFunction{
//		"NewDocumentFromUrl": NewDocumentFromUrl_4lua,
//	}))
//}

//func NewDocumentFromUrl_4lua(l *lua.LState) int {
//	// GoQuery.NewDocumentFromUrl("http://www.baidu.com")
//
//	url := l.ToString(1)
//	document, err := goquery.NewDocument(url)
//
//	if err != nil {
//		return luahelper.PushLuaStatusWithMessage(l, false, err.Error())
//	}
//
//	return 0
//}

func ConvertDocument2LuaTable(l *lua.LState, document *goquery.Document) (table *lua.LTable) {
	table = l.NewTable()

	return
}

func ConvertSelection2LuaTable(l *lua.LState, item interface{}) (table *lua.LTable) {
	metatable := l.NewTable()

	gostruct := l.NewUserData()
	gostruct.Value = item
	metatable.RawSetString("__gostruct", gostruct)
	metatable.RawSetString("__index", l.NewFunction(func(state *lua.LState) int {
		defer func() {
			if err, ok := recover().(error); ok {
				fmt.Println(err)
			}
		}()

		self := l.ToTable(1)
		if self == nil {
			return 0
		}

		funcName := l.ToString(2)
		selectionType := reflect.ValueOf(item)

		parameterCount := l.GetTop()

		var values []reflect.Value

		for i := 2; i <= parameterCount; i++ {
			luaValue := l.Get(i)
			if luaValue.Type() == lua.LTString {
				values = append(values, reflect.ValueOf(lua.LVAsString(luaValue)))
			} else if luaValue.Type() == lua.LTNumber {
				values = append(values, reflect.ValueOf(float64(lua.LVAsNumber(luaValue))))
			} else if luaValue.Type() == lua.LTBool {
				values = append(values, reflect.ValueOf(lua.LVAsBool(luaValue)))
			} else {
				values = append(values, reflect.ValueOf(nil))
			}
		}

		method := selectionType.MethodByName(funcName)
		responseValues := method.Call(values)

		for _, resp := range responseValues {
			if resp.Kind() == reflect.String {
				l.Push(lua.LString(resp.String()))
			} else if resp.Kind() == reflect.Float64 || resp.Kind() == reflect.Float32 {
				l.Push(lua.LNumber(resp.Float()))
			} else if resp.Kind() == reflect.Bool {
				l.Push(lua.LBool(resp.Bool()))
			} else {
				panic(errors.New("unknow type"))
			}
		}

		return len(responseValues)
	}))

	table = l.NewTable()

	return
}
